home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-09 | 6.1 KB | 215 lines | [TEXT/R*ch] |
- # uu.py
- # Copyright 1994 by Lance Ellinghouse
- # Cathedral City, California Republic, United States of America.
- # All Rights Reserved
- # Permission to use, copy, modify, and distribute this software and its
- # documentation for any purpose and without fee is hereby granted,
- # provided that the above copyright notice appear in all copies and that
- # both that copyright notice and this permission notice appear in
- # supporting documentation, and that the name of Lance Ellinghouse
- # not be used in advertising or publicity pertaining to distribution
- # of the software without specific, written prior permission.
- # LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
- # THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- # FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE
- # FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- # This file implements the UUencode and UUdecode functions.
-
- # encode(filename, mode, in_file, out_file)
- # decode(filename, mode, in_file)
- # decode(in_file, out_file)
- # decode(in_file)
-
- # encode a single char to always be printable
- def _ENC(ch):
- if type(ch) == type(''):
- a = ch[:1] # only 1 char
- if len(a) == 0:
- raise ValueError, 'need to pass in at least 1 char'
- a = ord(a)
- elif type(ch) == type(0):
- a = ch
- else:
- raise TypeError, 'must pass in an integer or single character'
- return chr((a & 077) + ord(' '))
-
- # input 3 chars, output 4 encoded chars
- def _outenc(str):
- if len(str) > 3:
- raise ValueError, 'can only accept strings of 3 chars'
- p0, p1, p2 = 0, 0, 0
- if len(str) > 2:
- p2 = ord(str[2])
- if len(str) > 1:
- p1 = ord(str[1])
- if len(str) > 0:
- p0 = ord(str[0])
- c1 = p0 >> 2
- c2 = (p0 << 4) & 060 | (p1 >> 4) & 017
- c3 = (p1 << 2) & 074 | (p2 >> 6) & 03
- c4 = p2 & 077
- rtn = _ENC(c1)
- rtn = rtn + _ENC(c2)
- rtn = rtn + _ENC(c3)
- rtn = rtn + _ENC(c4)
- return rtn
-
- # pass in 45 bytes max, returns 62 bytes encoded
- def _encode(str):
- if len(str) > 45:
- raise ValueError, 'cannot handle more than 45 chars at once'
- length = len(str)
- rtn = _ENC(length)
- i = 0
- while i < length:
- rtn = rtn + _outenc(str[i:(i+3)])
- i = i + 3
- rtn = rtn + '\n'
- return rtn
-
- # encode a fileobject and write out to a file object
- def encode(filename, mode, in_file, out_file):
- out_file.write('begin %o %s\n' % ((mode&0777),filename))
- str = in_file.read(45)
- while len(str) > 0:
- out_file.write(_encode(str))
- str = in_file.read(45)
- out_file.write(' \nend\n')
- return None
-
- # def decode a single char from printable to possibly non-printable
- def _DEC(ch):
- if type(ch) != type('') or len(ch) != 1:
- raise ValueError, 'need to pass in a single char'
- a = ord(ch[0:1])
- return (a - ord(' '))
-
- # input 4 chars encoded, output 3 chars unencoded
- def _outdec(str):
- if len(str) > 4:
- raise ValueError, 'can only accept strings of 4 chars'
- p0, p1, p2, p3 = 0, 0, 0, 0
- if len(str) > 3:
- p3 = _DEC(str[3])
- if len(str) > 2:
- p2 = _DEC(str[2])
- if len(str) > 1:
- p1 = _DEC(str[1])
- if len(str) > 0:
- p0 = _DEC(str[0])
- c1 = p0 << 2 | (p1 & 060) >> 4
- c2 = (p1 & 017) << 4 | (p2 & 074) >> 2
- c3 = (p2 & 03) << 6 | (p3 & 077)
- rtn = chr(c1)
- rtn = rtn + chr(c2)
- rtn = rtn + chr(c3)
- return rtn
-
- # pass in 62 bytes and return 45 bytes unencoded
- def _decode(str):
- if len(str) > 62:
- raise ValueError, 'cannot handle more than 62 chars at once'
- length = _DEC(str[0])
- i = 1
- rtn = ''
- while len(rtn) < length:
- rtn = rtn + _outdec(str[i:(i+4)])
- i = i + 4
- return rtn[0:length]
-
- # decode(filename, mode, in_file)
- # decode(in_file, out_file)
- # decode(in_file)
- def decode(*args):
- ok = 1
- _setup = None
- out_file = None
- if len(args) == 3:
- filename, mode, in_file = args
- if type(filename) != type(''):
- ok = 0
- if type(mode) != type(0):
- ok = 0
- try:
- _ = getattr(in_file,'readline')
- except AttributeError:
- ok = 0
- def _setup(out_file,args):
- filename, mode, in_file = args
- # open file as specified and assign out_file for later use
- out_file = open(filename,'w',mode)
- _out_file_orig = 0
- _ = in_file.readline()
- return (out_file,_out_file_orig)
- elif len(args) == 2:
- in_file, out_file = args
- try:
- _ = getattr(in_file,'readline')
- _ = getattr(out_file,'write')
- except AttributeError:
- ok = 0
- def _setup(out_file, args):
- in_file, out_file = args
- # Toss the 'begin mode filename' part.. not needed
- _ = in_file.readline()
- _out_file_orig = 1
- return (out_file,_out_file_orig)
- elif len(args) == 1:
- in_file = args[0]
- try:
- _ = getattr(in_file,'readline')
- except AttributeError:
- ok = 0
- def _setup(out_file, args):
- import strop
- in_file = args[0]
- # open file as specified in uu file and
- # assign out_file for later use
- i = in_file.readline()
- i = strop.strip(i)
- if 'begin' != i[:5]:
- raise IOError, 'input file not in UUencoded format'
- [dummy, mode, filename] = strop.split(i)
- mode = strop.atoi(mode, 8)
- out_file = open(filename,'w',mode)
- _out_file_orig = 0
- return (out_file,_out_file_orig)
- if ok != 1:
- raise SyntaxError, 'must be (filename, mode, in_file) or (in_file,out_file) or (in_file)'
- out_file, _out_file_orig = _setup(out_file, args)
- str = in_file.readline()
- while len(str) > 0 and str != ' \n' and str != 'end\n':
- out_file.write(_decode(str))
- str = in_file.readline()
- if _out_file_orig == 0:
- out_file.close()
- del out_file
- return None
-
- def test():
- import sys
- if sys.argv[1:2] == ['-d']:
- if sys.argv[2:]:
- decode(open(sys.argv[2]), sys.stdout)
- else:
- decode(sys.stdin, sys.stdout)
- elif sys.argv[1:2] == ['-e']:
- if sys.argv[2:]:
- file = sys.argv[2]
- fp = open(file)
- else:
- file = '-'
- fp = sys.stdin
- encode(file, 0644, fp, sys.stdout)
- else:
- print 'usage: uu -d [file]; (to decode)'
- print 'or: uu -e [file]; (to encode)'
- sys.exit(2)
-
- if __name__ == '__main__':
- test()
-